package com.gitee.feizns.quickstart.demo;

import com.intelligt.modbus.jlibmodbus.Modbus;
import com.intelligt.modbus.jlibmodbus.data.ModbusHoldingRegisters;
import com.intelligt.modbus.jlibmodbus.slave.ModbusSlave;
import com.intelligt.modbus.jlibmodbus.slave.ModbusSlaveFactory;
import com.intelligt.modbus.jlibmodbus.tcp.TcpParameters;

import java.net.InetAddress;

/**
 * @author feizns
 * @since 2025/1/7
 */
public class ModServer {

    public static void main(String[] args) {
        try {
// 设置从机TCP参数
            TcpParameters tcpParameters = new TcpParameters();
            // 设置TCP的ip地址
            InetAddress address = InetAddress.getByName("127.0.0.1");
            // getLocalHost()返回的是本机地址
            // tcpParameters.setHost(InetAddress.getLocalHost());
            // 为从机TCP设置上述ip地址参数
            tcpParameters.setHost(address);
            // 设置从机TCP的是否长连接，通俗点讲就是一直保持连接，一次连接完下次就不要在连接了
            tcpParameters.setKeepAlive(true);
            // 设置从机TCP的端口
            tcpParameters.setPort(Modbus.TCP_PORT);
            // 创建一个从机
            ModbusSlave slave = ModbusSlaveFactory.createModbusSlaveTCP(tcpParameters);
            // 设置控制台输出主机和从机命令交互日志
            Modbus.setLogLevel(Modbus.LogLevel.LEVEL_DEBUG);
            slave.setReadTimeout(100000);
            // 启动服务器
            // 设置从机寄存器的03和04功能码对应的数值寄存器
            ModbusHoldingRegisters hr = new ModbusHoldingRegisters(10);
            // 修改数值寄存器对应位置的值，第一个参数代表寄存器地址，第二个代表修改的数值
            hr.set(0, 123);
            hr.set(1, 456);
            // 为从机设置04功能码对应的数值寄存器
            slave.getDataHolder().setInputRegisters(hr);
            // 为从机设置03功能码对应的数值寄存器
            slave.getDataHolder().setHoldingRegisters(hr);
            // 为从机设置01功能码对应的数值寄存器
//            slave.getDataHolder().setCoils(mc);
            // 为从机设置从机服务地址slaveid
            slave.setServerAddress(1);
            // 开启从机监听事件，必须要这一句
            slave.listen();
            //这部分代码主要是设置Java虚拟机关闭的时候需要做的事情，即本程序关闭的时候需要做的事情，直接使用即可
//            if (slave.isListening()) {
//                Runtime.getRuntime().addShutdownHook(new Thread() {
//                    @Override
//                    public void run() {
//                        synchronized (slave) {
//                            slave.notifyAll();
//                        }
//                    }
//                });
//
//                synchronized (slave) {
//                    slave.wait();
//                }
//                /*
//                 * using master-branch it should be #slave.close();
//                 */
//                slave.shutdown();
//            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

}
